package com.lgl.scsapi.util.utils;

import com.lgl.scsapi.system.model.PageData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

public class AppUtil  {
	private static Logger log = LoggerFactory.getLogger(AppUtil.class);

	/**
	 * 设置list中的distance
	 */
	/*public staticFile List<PageData>  setListDistance(List<PageData> list, PageData pd){
		List<PageData> listReturn = new ArrayList<PageData>();
		String user_longitude = "";
		String user_latitude = "";
		
		try{
			user_longitude = pd.get("user_longitude").toString(); //"117.11811";
			user_latitude  = pd.get("user_latitude").toString();  //"36.68484";
		} catch(Exception e){
			log.error("缺失参数--user_longitude和user_longitude");
			log.error("lost param：user_longitude and user_longitude");
		}
		
		PageData pdTemp = new PageData();
		int size = list.size();
		for(int i=0;i<size;i++){
			pdTemp = list.get(i);
			String longitude = pdTemp.get("longitude").toString();
			String latitude = pdTemp.get("latitude").toString();
			String distance = MapUtil.getDistance(
						user_longitude,	user_latitude,
						longitude,		latitude
					);
			pdTemp.put("distance", distance);
			pdTemp.put("size", distance.length());
			listReturn.add(pdTemp);
		}
		return listReturn;
	}*/
	/**
	 * 获取classpath
	 * @return
	 */
	public static String getClassPath(){
		String path = (String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""))+"../../").replaceAll("file:/", "").replaceAll("%20", " ").trim();	
		if(path.indexOf(":") != 1){
			path = File.separator + path;
		}
		return path;
	}
	/**
	 * 获取客户端真实IP地址
	 * 注：需在nginx作如下配置：
	 * proxy_set_header Host $http_host;  包含客户端真实的域名和端口号
		proxy_set_header X-Real-IP $remote_addr;  表示客户端真实的IP
		//这个Header和X-Real-IP类似，但它在多层代理时会包含真实客户端及中间每个代理服务器的IP。
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;  表示客户端真实的协议（http还是https）
		
		在tomcat中作如下配置：
		在server.xml中的<Host>节点中添加如下内容：<Valve className="org.apache.catalina.valves.RemoteIpValve" />
	 * @param request
	 * @return
	 */
	public static String getIPAddress(HttpServletRequest request) {
		String ip = request.getRemoteAddr();
		if(StringUtils.hasText(ip) && !"unKnown".equalsIgnoreCase(ip)){
			return ip;
		}
		ip = request.getHeader("X-Forwarded-For");
		if(StringUtils.hasText(ip) && !"unKnown".equalsIgnoreCase(ip)){
			//多次反向代理后会有多个ip值，第一个ip才是真实ip
			int index = ip.indexOf(",");
			if(index != -1){
				return ip.substring(0,index);
			}
			return ip;
		}
		return request.getHeader("X-Real-IP");
	}
	/**
	 * 获取资源路径
	 * @return
	 */
	/*public staticFile String getClassResources(){
		String path =  (String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""))).replaceAll("file:/", "").replaceAll("%20", " ").trim();
		if(path.indexOf(":") != 1){
			path = File.separator + path;
		}
		return path;
	}*/

	public static void responseWrite(HttpServletResponse response, String jsonStr) {
		PrintWriter writer = null;
		try {
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-Type", "application/json;charset=UTF-8");
			writer = response.getWriter();
			writer.write(jsonStr);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (writer != null) {
				writer.flush();
				writer.close();
			}
		}
	}
	/**
	 * 校验同一IP或同一个手机号码3小时内是否已获取5次验证码
	 * @param redisKey
	 * @param checkFlag
	 * @return
	 */
	public static String checkPhoneAndIP(StringRedisTemplate stringRedisTemplate, String redisKey, String checkFlag){
		String phoneSendNumberStr = stringRedisTemplate.opsForValue().get(redisKey);
		if (StringUtils.hasText(phoneSendNumberStr)) {
			//同一手机号码，3小时内获取验证码的次数不超过5次
			int phoneSendNumber = Integer.parseInt(phoneSendNumberStr);
			if (phoneSendNumber >= Constants.CHECK_CODE_MAX_TIMES) {
				return checkFlag;
			}
			phoneSendNumber ++;
			//key还剩余多少秒过期
			long keySurplusLiveSecond = stringRedisTemplate.getExpire(redisKey);
			stringRedisTemplate.opsForValue().set(redisKey, String.valueOf(phoneSendNumber), (int) keySurplusLiveSecond, TimeUnit.SECONDS);
		}else {
			//3小时
			stringRedisTemplate.opsForValue().set(redisKey, "1", 10800,TimeUnit.SECONDS);
		}
		return null;
	}
	/**
	 * 验证并发送验证码
	 * @param request 通过HttpServletRequest对象获取用户IP地址
	 * @param phone 接收验证码的手机号
	 * @param pd 返回状态码的PageData对象
	 * @param stringRedisTemplate 用于从redis中获取IP，手机号获取验证码的次数
	 * @return 状态码的PageData对象
	 */
	public static PageData checkAndSendCode(HttpServletRequest request, String phone, PageData pd, StringRedisTemplate stringRedisTemplate){
		if (Constants.REDIS_IS_USABLE) {
			//以下代码，控制同一手机号3小时内最多获取5次验证码,
			//如果手机号不为空，则已发送过一次验证码
			String checkResult = checkPhoneAndIP(stringRedisTemplate,Constants.PHONE_SEND_TIMES + phone, "5");
			if (StringUtils.hasText(checkResult)) {
				pd.put("status", checkResult); //手机号码发送验证码已超过5次
				return pd;
			}
			String clientIP = AppUtil.getIPAddress(request);
			//以下代码，控制同一IP3小时内最多获取5次验证码
			checkResult = checkPhoneAndIP(stringRedisTemplate,Constants.PHONE_SEND_TIMES + clientIP, "4");
			//客户端IP地址发送验证码已超过5次
			if (StringUtils.hasText(checkResult)) {
				pd.put("status", checkResult);
				return pd;
			}
		}

		int randomNum = Tools.getRandomNum();
		//注：此为短信发送的模板，不可修改，否则会发送不出短信，模板可在平台上修改或添加成自己想要的模板
		String checkWord = "您的验证码是" + randomNum + "，在20分钟内输入有效，如非本人操作请忽略此短信。";
		//给手机发送验证码
		//SmsUtil.singleSend(phone, checkWord);
		//20分钟
		log.info(phone + checkWord);
		stringRedisTemplate.opsForValue().set(Constants.PHONE_CHECK_CODE_K_PRE + phone, String.valueOf(randomNum), 1200, TimeUnit.SECONDS);
		pd.clear();
		pd.put("status", "1");
		return pd;
	}
}
